`timescale 1ns/100ps

//`define IVERILOG

module riscv_tb();

integer r;

reg rst;
reg clk;
reg [3:1] key;
reg [7:0] dip;
wire [4:1] leda;
wire [7:0] ledb;
wire beep;
wire uart_rx;
wire uart_tx;

reg [7:0] dipc;
wire [7:0] seg_data;
wire [3:0] seg_en;
wire [7:0] ledc;
wire oled_scl; 
wire oled_sda;

riscv_core riscv_c0(
    .RST(rst), 
    .CLK(clk), 
    .KEY(key), 
    .DIPB(dip), 
    .LEDA(leda), 
    .LEDB(ledb), 
    .BEEP(beep), 
    .UART_RX(uart_rx), 
    .UART_TX(uart_tx),
    .SEG_DATA(seg_data),
    .SEG_EN(seg_en),
    .DIPC(dipc),
    .LEDC(ledc),
    .OLED_SCL(oled_scl),
    .OLED_SDA(oled_sda)
);

assign uart_rx = uart_tx;

always #5 clk = ~clk;

initial begin
`ifdef IVERILOG
    string inst_file0;
    string inst_file1;
    string data_file0;
    string data_file1;
    string data_file2;
    string data_file3;

    if ($value$plusargs("inst_file0=%s", inst_file0)) begin
        $display("inst_file0 = %s", inst_file0);
        $readmemh(inst_file0, riscv_c0.inst_rom_unit.inst_rom_u0.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.h00", riscv_c0.inst_rom_unit.inst_rom_u0.mem);
    end

    if ($value$plusargs("inst_file1=%s", inst_file1)) begin
        $display("inst_file1 = %s", inst_file1);
        $readmemh(inst_file1, riscv_c0.inst_rom_unit.inst_rom_u1.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.h01", riscv_c0.inst_rom_unit.inst_rom_u1.mem);
    end


    if ($value$plusargs("data_file0=%s", data_file0)) begin
        $display("data_file0 = %s", data_file0);
        $readmemh(data_file0, riscv_c0.data_ram_unit.data_ram_u0.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.d00", riscv_c0.data_ram_unit.data_ram_u0.mem);
    end

    if ($value$plusargs("data_file1=%s", data_file1)) begin
        $display("data_file1 = %s", data_file1);
        $readmemh(data_file1, riscv_c0.data_ram_unit.data_ram_u1.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.d01", riscv_c0.data_ram_unit.data_ram_u1.mem);
    end

    if ($value$plusargs("data_file2=%s", data_file2)) begin
        $display("data_file2 = %s", data_file2);
        $readmemh(data_file2, riscv_c0.data_ram_unit.data_ram_u2.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.d02", riscv_c0.data_ram_unit.data_ram_u2.mem);
    end

    if ($value$plusargs("data_file3=%s", data_file3)) begin
        $display("data_file3 = %s", data_file3);
        $readmemh(data_file3, riscv_c0.data_ram_unit.data_ram_u3.mem);
    end else begin
        $readmemh("./sw/rv32ui-p-lw.d03", riscv_c0.data_ram_unit.data_ram_u3.mem);
    end
`else
    $readmemh("/msys64/home/mphya/fpga/isim/rv32ui-p-test_00.hex", riscv_c0.inst_rom_unit.inst_rom_u0.mem);
    $readmemh("/msys64/home/mphya/fpga/isim/rv32ui-p-test_01.hex", riscv_c0.inst_rom_unit.inst_rom_u1.mem);
    $readmemh("/msys64/home/mphya/fpga/dsim/rv32ui-p-test_00.hex", riscv_c0.data_ram_unit.data_ram_u0.mem);
    $readmemh("/msys64/home/mphya/fpga/dsim/rv32ui-p-test_01.hex", riscv_c0.data_ram_unit.data_ram_u1.mem);
    $readmemh("/msys64/home/mphya/fpga/dsim/rv32ui-p-test_02.hex", riscv_c0.data_ram_unit.data_ram_u2.mem);
    $readmemh("/msys64/home/mphya/fpga/dsim/rv32ui-p-test_03.hex", riscv_c0.data_ram_unit.data_ram_u3.mem);
`endif

    $display("inst[0]=%4h\n", riscv_c0.inst_rom_unit.inst_rom_u0.mem[0]);

	clk = 0;
	rst = 1;

	#40 rst = 0; 	//0有效

	#40 rst = 1;

    #40

    wait(leda[1:1]==1'b1 || leda[2:2]==1'b1) 
    #100
    if (leda[1:1] == 1'b1) begin
        $display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~");
        $display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        $display("~~~~~~~~~ #####     ##     ####    #### ~~~~~~~~~");
        $display("~~~~~~~~~ #    #   #  #   #       #     ~~~~~~~~~");
        $display("~~~~~~~~~ #    #  #    #   ####    #### ~~~~~~~~~");
        $display("~~~~~~~~~ #####   ######       #       #~~~~~~~~~");
        $display("~~~~~~~~~ #       #    #  #    #  #    #~~~~~~~~~");
        $display("~~~~~~~~~ #       #    #   ####    #### ~~~~~~~~~");
        $display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    end else begin
        $display("~~~~~~~~~~~~~~~~~~~ TEST_FAIL ~~~~~~~~~~~~~~~~~~~~");
        $display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        $display("~~~~~~~~~~######    ##       #    #     ~~~~~~~~~~");
        $display("~~~~~~~~~~#        #  #      #    #     ~~~~~~~~~~");
        $display("~~~~~~~~~~#####   #    #     #    #     ~~~~~~~~~~");
        $display("~~~~~~~~~~#       ######     #    #     ~~~~~~~~~~");
        $display("~~~~~~~~~~#       #    #     #    #     ~~~~~~~~~~");
        $display("~~~~~~~~~~#       #    #     #    ######~~~~~~~~~~");
        $display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    end

`ifdef IVERILOG
    $finish;
`endif
end

initial begin
    #500000
    $display("Time Out.");
    $finish;
end

endmodule

